Add time tracking to http status agent (#1517)

* Add time tracking to http status agent

* Replace time tracking to monotonic

* Add tests for time tracker

Pablo Carranza 8 years ago
parent
commit
74a3c88608

+ 7 - 6
app/models/agents/http_status_agent.rb

@@ -14,7 +14,7 @@ module Agents
14 14
     form_configurable :disable_redirect_follow, type: :array, values: ['true', 'false']
15 15
 
16 16
     description <<-MD
17
-      The HttpStatusAgent will check a url and emit the resulting HTTP status code.
17
+      The HttpStatusAgent will check a url and emit the resulting HTTP status code with the time that it waited for a reply.
18 18
 
19 19
       Specify a `Url` and the Http Status Agent will produce an event with the http status code.
20 20
 
@@ -27,6 +27,7 @@ module Agents
27 27
           {
28 28
             "url": "...",
29 29
             "status": "..."
30
+            "elapsed_time": "..."
30 31
           }
31 32
     MD
32 33
 
@@ -60,11 +61,12 @@ module Agents
60 61
     private
61 62
 
62 63
     def check_this_url(url)
63
-      if result = ping(url)
64
-        create_event payload: { 'url' => url, 'status' => result.status.to_s, 'response_received' => true }
65
-        memory['last_status'] = result.status.to_s
64
+      measured_result = TimeTracker.track { ping(url) }
65
+      if measured_result.result
66
+        create_event payload: { 'url' => url, 'status' => measured_result.status.to_s, 'response_received' => true, 'elapsed_time' => measured_result.elapsed_time }
67
+        memory['last_status'] = measured_result.status.to_s
66 68
       else
67
-        create_event payload: { 'url' => url, 'response_received' => false }
69
+        create_event payload: { 'url' => url, 'response_received' => false, 'elapsed_time' => measured_result.elapsed_time }
68 70
         memory['last_status'] = nil
69 71
       end
70 72
     end
@@ -75,7 +77,6 @@ module Agents
75 77
     rescue
76 78
       nil
77 79
     end
78
-
79 80
   end
80 81
 
81 82
 end

+ 22 - 0
lib/time_tracker.rb

@@ -0,0 +1,22 @@
1
+class TimeTracker
2
+  attr_accessor :elapsed_time, :result
3
+
4
+  def self.track
5
+    start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
6
+    result = yield
7
+    new(Process.clock_gettime(Process::CLOCK_MONOTONIC) - start, result)
8
+  end
9
+
10
+  def initialize(elapsed_time, result)
11
+    @elapsed_time = elapsed_time
12
+    @result = result
13
+  end
14
+
15
+  def method_missing(method_sym, *arguments, &block)
16
+    if @result.respond_to?(method_sym)
17
+      @result.send(method_sym, *arguments, &block)
18
+    else
19
+      super
20
+    end
21
+  end
22
+end

+ 11 - 0
spec/controllers/http_status_agent_spec.rb

@@ -133,6 +133,11 @@ describe 'HttpStatusAgent' do
133 133
         expect(agent.memory['last_status']).to eq('200')
134 134
       end
135 135
 
136
+      it "should record the time spent waiting for the reply" do
137
+        agent.receive events
138
+        expect(agent.the_created_events[0][:payload]['elapsed_time']).not_to be_nil
139
+      end
140
+
136 141
       describe "but the status code is not 200" do
137 142
         let(:status_code) { 500 }
138 143
 
@@ -236,6 +241,12 @@ describe 'HttpStatusAgent' do
236 241
           expect(agent.the_created_events[1][:payload]['url']).to eq(failing_url)
237 242
         end
238 243
 
244
+        it "should record the time spent waiting for the reply" do
245
+          agent.receive events
246
+          expect(agent.the_created_events[0][:payload]['elapsed_time']).not_to be_nil
247
+          expect(agent.the_created_events[1][:payload]['elapsed_time']).not_to be_nil
248
+        end
249
+
239 250
       end
240 251
 
241 252
     end

+ 21 - 0
spec/lib/time_tracker_spec.rb

@@ -0,0 +1,21 @@
1
+require 'rails_helper'
2
+
3
+describe TimeTracker do
4
+  describe "#track" do
5
+    it "tracks execution time" do
6
+      tracked_result = TimeTracker.track { sleep(0.01) }
7
+      expect(tracked_result.elapsed_time).to satisfy {|v| v > 0.01 && v < 0.1}
8
+    end
9
+
10
+    it "returns the proc return value" do
11
+      tracked_result = TimeTracker.track { 42 }
12
+      expect(tracked_result.result).to eq(42)
13
+    end
14
+
15
+    it "returns an object that behaves like the proc result" do
16
+      tracked_result = TimeTracker.track { 42 }
17
+      expect(tracked_result.to_i).to eq(42)
18
+      expect(tracked_result + 1).to eq(43)
19
+    end
20
+  end
21
+end